/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#ifndef __PERFORMANCE_DATA_OBJECT_HDR__
#define __PERFORMANCE_DATA_OBJECT_HDR__

#pragma warning( disable : 4786 )

#include <limits>
#include <map>
#include <string>
#include <vector>

namespace performance {

	//
	//
	//
	const double NAN = std::numeric_limits<double>::quiet_NaN();


    //
    // wake turbulance category
    //
    enum LHM_CAT { L, M, H };


	//
	// Performance Data type information
	//
	struct PDT {

//		PDT();
//		PDT( const PDT & );
//		~PDT();

		std::string type;        // aircraft type
		LHM_CAT     wtc;         // wake turbulence category, L/M/H
		int         syMSC;       // Sydney MAESTRO speed class, 0-10
		int         bnMSC;       // Brisbane MAESTRO speed class, 0-10

		int         classRef;    // class number, 0-99

	};


	//
	// Data Structure for altitude banded data
	//
	struct AltitudeData {
		double level;			// layer altitudes, ft
		double climbRate;		// climb rate, ft/Min
		double descendRate;		// descend rate, ft/Min
		double acceleration;	// acceleration, Kt/Min
		double deceleration;	// deceleration, Kt/Min
		double cruiseSpeed;		// cruising speed, Kt true
		double stallSpeed;		// stall speed, Kt true
		double climbSpeed;		// speed climbing, Kt true
		double descendSpeed;	// speed descending, Kt true
		double maximumSpeed;

		double getClimbRate()    const { return climbRate; }
		double getDescendRate()  const { return descendRate; }
		double getAcceleration() const { return acceleration; }
		double getDeceleration() const { return deceleration; }
		double getCruiseSpeed()  const { return cruiseSpeed; }
		double getStallSpeed()   const { return stallSpeed; }
		double getClimbSpeed()   const { return climbSpeed; }
		double getDescendSpeed() const { return descendSpeed; }
		double getMaximumSpeed() const { return maximumSpeed; }
	};


	//
	// Performance Data Object
	//
	struct PDO {

//		PDO();
//		PDO( const PDO & );
//		~PDO();

		int    classNo;     // class number, 0-99

		double lowHold;     // low level (?<6000) holding speed, Kt true
		double midHold;     // mid level ...
		double uppHold;     // upper level (?>14000) ...

		double toSpeed;     // takeoff speed, Kt true
		double toDuration;  // takeoff duration, Sec
		double toAltitude;  // takeoff altitude, ft
		double toDistance;  // takeoff distance, NM

		double finSpeed;    // final landing speed, Kt true
		double xSection;    // (radar) cross section, m^2 0-1000

		double maxSpeed;    // maximum speed, Kt true
		double maxAltitude; // maximum altitude, ft
		double maxTurnSp;   // maximum turn speed, deg/Sec

        bool is_mach;		// is Mach capable
        bool is_jet;		// is jet

		double stdTurnSp;   // standard turn speed, deg/Sec

		double redTurn;     // reduced turn rate, ratio
		double accTurn;     // accelerated ...
		double maxTurn;     // maximum ...

		double redAccel;    // reduced accelaration, ratio
		double accAccel;    // accelerated ...
		double maxAccel;    // maximum ...

		double redDecel;    // reduced deceleration, ratio
		double accDecel;    // accelerated ...
		double maxDecel;    // maximum ...

		double redClimb;    // reduced climb rate, ratio
		double accClimb;    // accelerated ...
		double maxClimb;    // maximum ...

		double redDescend;  // reduced descend rate, ratio
		double accDescend;  // accelerated ...
		double maxDescend;  // maximum ...

		std::vector< AltitudeData > *levelData;

		LHM_CAT  sidStar;          // SID/STAR category, H/M/L
    };


	//
	// performance::Data
	// 
	class Data {

	public:
//		Data();
//		~Data();

		friend class Builder;
		friend class Writer;

	public:
//		void add_type( const PDT& );
//		void add_performance( const PDO& );

		const PDT * lookup_type( const std::string & ) const;
		const PDO * lookup_data( int ) const;

	protected:
		std::map< std::string, const PDT * > _type;
		std::map<         int, const PDO * > _performance;

	};


	//
	//
	//
	typedef const std::auto_ptr< Data >  DataCPtr;
	typedef std::map< std::string, const PDT * > PDTMap;
	typedef std::map<         int, const PDO * > PDOMap;

	//
	//
	//

	typedef std::vector< AltitudeData >           AltData;
	typedef std::vector< AltitudeData >::iterator AltDataIt;


};

#endif
